package com.visikard.application;

import java.util.HashMap;

import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.app.Application;
import android.content.Context;
import android.content.SharedPreferences;
import android.util.DisplayMetrics;
import android.util.Log;

import com.nostra13.universalimageloader.cache.disc.naming.HashCodeFileNameGenerator;
import com.nostra13.universalimageloader.core.assist.QueueProcessingType;
import com.visikard.item.MerchantAccountObj;
import com.visikard.item.VKregisterMerchantSession;
import com.visikard.system.VKMerchantSessionStore;
import com.visikard.utility.Prefs;

public class VKRegApplication extends Application {

	// flag for Debugging
	private static final String PREF_VKREG = "vkregapplication_prefs";
	private static final String PREF_MERCHANT_OBJ = "key_merchant_obj";
	public static final boolean IS_DEBUGGING = false;
	public static final boolean IS_LOGGING = true;
	public static final boolean IS_TESTING = false;

	private static final String TAG = VKRegApplication.class.getSimpleName();

	public static VKRegApplication instance;
	public static int screenVisibleHeight = 0;
	public static int mPageSize = 100;
	public static long uid = Constant.INVALID_ID;
	public static String loginSession = "";
	// for merchant login
	public static MerchantAccountObj merchantAccountObj = null;

	/** application context */
	private Context mContext = null;

	public void setContext(Context C) {
		this.mContext = C;
	}

	public Context getContext() {
		return this.mContext;
	}

	/** visikard application session */
	private VKregisterMerchantSession mSession = null;

	public void saveMerchantSession(VKregisterMerchantSession session) {
		mSession = session;
		VKMerchantSessionStore.save(mSession, mContext);
	}

	public VKregisterMerchantSession restoreMerchantSession() {
		return VKMerchantSessionStore.restore(mContext);
	}

	public void removeMerchantSession() {
		VKMerchantSessionStore.clear(mContext);
	}

	public void saveSessionAddress(String address) {
		VKMerchantSessionStore.saveAddress(address, mContext);
	}

	public String restoreSessionAddress() {
		String location = VKMerchantSessionStore.restoreAdress(mContext);
		Log.d("NghiDo", "get address?: " + location);
		if (location == null)
			return "";
		else
			return location;
	}

	/*
	 * Hash map cache data
	 */
	private HashMap<Object, Object> _data = new HashMap<Object, Object>();

	public void putData(Object key, Object value) {
		try {
			_data.put(key, value);
		}
		catch (OutOfMemoryError e) {
			e.printStackTrace();
			System.gc();
		}
	}

	public void removeData(Object key) {
		if (getData(key) != null)
			_data.remove(key);
	}

	public Object getData(Object key) {
		return _data.get(key);
	}

	private Prefs mPrefs;

	public void setmPrefs(Prefs mPrefs) {
		this.mPrefs = mPrefs;
	}

	public Prefs getmPrefs() {
		return mPrefs;
	}

	@Override
	public void onCreate() {
		Log.d(TAG, "onCreate()");
		super.onCreate();

		// create visikard application instance
		instance = this;

		// create visikard application context for context
		mContext = getApplicationContext();

		// mConfig = new VisikardConfig(mContext);

		// set default handler exception to catch
		// Thread.setDefaultUncaughtExceptionHandler(unCaughtExceptionHandler);

		// init application objects
		initObjects();

		mPrefs = new Prefs(this);
		setmPrefs(mPrefs);

	}

	@Override
	public void onTerminate() {
		Log.d(TAG, "onTerminate()");
		super.onTerminate();

		// cancel all notification
		// TODO

		// stop all service
		// TODO

		// remove all broadcast
		// TODO

		// close db connection
		// TODO
	}

	/**
	 * init application objects
	 * load instances, connect db, session,...
	 */
	private void initObjects() {
		// create async task
		initUILImageLoader(this);
		// session

		// merchant obj
		SharedPreferences prefs = getSharedPreferences(PREF_VKREG, MODE_PRIVATE);
		String strMerchantObj = prefs.getString(PREF_MERCHANT_OBJ, "");
		if (!strMerchantObj.isEmpty()) {
			try {
				merchantAccountObj = new MerchantAccountObj(new JSONObject(strMerchantObj));
			}
			catch (JSONException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	public void exitApp() {
		try {
			uid = -1;
			merchantAccountObj = null;
			removeMerchantObjFromPrefs();
		}
		catch (Exception e) {
			e.printStackTrace();
		}
	}

	// TODO: move to application level
	// @SuppressWarnings({ "static-access", "deprecation" })
	public void logout() {
		uid = -1;
		merchantAccountObj = null;
		removeMerchantSession();
		removeMerchantObjFromPrefs();
	}

	private void removeMerchantObjFromPrefs() {
		SharedPreferences prefs = getSharedPreferences(PREF_VKREG, MODE_PRIVATE);
		prefs.edit().putString(PREF_MERCHANT_OBJ, "").commit();
	}

	public void initUILImageLoader(Context context) {
		com.nostra13.universalimageloader.core.ImageLoaderConfiguration config = new com.nostra13.universalimageloader.core.ImageLoaderConfiguration.Builder(
				context).threadPriority(Thread.NORM_PRIORITY - 2).denyCacheImageMultipleSizesInMemory()
				.diskCacheFileNameGenerator(new HashCodeFileNameGenerator())
				.tasksProcessingOrder(QueueProcessingType.LIFO).writeDebugLogs() // Remove for release app
				.memoryCacheSizePercentage(10).diskCacheSize(300 * 1024 * 1024)

				.build();
		// Initialize ImageLoader with configuration.
		com.nostra13.universalimageloader.core.ImageLoader.getInstance().init(config);
	}

	public int[] getDimensionDevice(Activity context) {
		DisplayMetrics displaymetrics = new DisplayMetrics();
		context.getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
		int height = displaymetrics.heightPixels;
		int width = displaymetrics.widthPixels;
		int[] dimen = new int[2];
		dimen[0] = width;
		dimen[1] = height;

		return dimen;
	}

	public float getDensity() {
		return getResources().getDisplayMetrics().density;
	}

	public int getStatusBarHeight(Activity context) {
		int result = 0;
		int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
		if (resourceId > 0) {
			result = context.getResources().getDimensionPixelSize(resourceId);
		}
		return result;
	}

	@Override
	public void onLowMemory() {
		Log.d(TAG, "onLowMemory()");

		super.onLowMemory();

		if (merchantAccountObj != null) {
			try {
				SharedPreferences prefs = getSharedPreferences(PREF_VKREG, MODE_PRIVATE);
				prefs.edit().putString(PREF_MERCHANT_OBJ, merchantAccountObj.toJSON()).commit();
			}
			catch (JSONException ex) {

			}
		}
	}

	@Override
	public void onTrimMemory(int level) {
		Log.d(TAG, "onTrimMemory() + level: " + level);
		super.onTrimMemory(level);

		if (merchantAccountObj != null) {
			try {
				SharedPreferences prefs = getSharedPreferences(PREF_VKREG, MODE_PRIVATE);
				prefs.edit().putString(PREF_MERCHANT_OBJ, merchantAccountObj.toJSON()).commit();
			}
			catch (JSONException ex) {

			}
		}
	}

}
